package m.stock.v1;

import org.apache.commons.math3.util.Precision;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by maojianfeng on 8/5/16.
 */
public class TrendFinder {
    private static Logger logger = Logger.getLogger(TrendFinder.class);
    public static List<ResultWrapper> compute(List<StockRecord> records, int trendLength){
        List<ResultWrapper> resultWrappers = new ArrayList<ResultWrapper>();
        resultWrappers.addAll(computeMinus(records,trendLength));
        resultWrappers.addAll(computePositive(records,trendLength));
        return resultWrappers;
    }

    private static List<ResultWrapper> computeMinus(List<StockRecord> records, int trendLength){
        List<ResultWrapper> resultWrappers = new ArrayList<ResultWrapper>();
        if(records!=null){
            Collections.sort(records,new StockRecordComparator());
        }
        List<StockRecord> tmpRecords = new ArrayList<StockRecord>();
        for(StockRecord record:records){
            double macdComputed = record.getMacdComputed();
            if(macdComputed<=0){
                if(tmpRecords.isEmpty()){
                    tmpRecords.add(record);
                }else{
                    double macdComputedLast = tmpRecords.get(tmpRecords.size()-1).getMacdComputed();
                    if(macdComputed>macdComputedLast){
                        tmpRecords.add(record);
                    }else if(macdComputed==macdComputedLast){
                        if(tmpRecords.size()>=trendLength){
                            resultWrappers.add(harvestResult(tmpRecords,1));
                        }
                        tmpRecords.clear();
                        tmpRecords.add(record);
                    }else{
                        if(tmpRecords.size()>=trendLength){
                            resultWrappers.add(harvestResult(tmpRecords,1));
                        }
                        tmpRecords.clear();
                        tmpRecords.add(record);
                    }
                }
            }
        }
        if(tmpRecords.size()>=trendLength){
            resultWrappers.add(harvestResult(tmpRecords,1));
        }
        return resultWrappers;
    }

    private static List<ResultWrapper> computePositive(List<StockRecord> records, int trendLength){
        List<ResultWrapper> resultWrappers = new ArrayList<ResultWrapper>();
        if(records!=null){
            Collections.sort(records,new StockRecordComparator());
        }
        List<StockRecord> tmpRecords = new ArrayList<StockRecord>();
        for(StockRecord record:records){
            double macdComputed = record.getMacdComputed();
            if(macdComputed>=0){
                if(tmpRecords.isEmpty()){
                    tmpRecords.add(record);
                }else{
                    double macdComputedLast = tmpRecords.get(tmpRecords.size()-1).getMacdComputed();
                    if(macdComputed<macdComputedLast){
                        tmpRecords.add(record);
                    }else if(macdComputed==macdComputedLast){
                        if(tmpRecords.size()>=trendLength){
                            resultWrappers.add(harvestResult(tmpRecords,2));
                        }
                        tmpRecords.clear();
                        tmpRecords.add(record);
                    }else{
                        if(tmpRecords.size()>=trendLength){
                            resultWrappers.add(harvestResult(tmpRecords,2));
                        }
                        tmpRecords.clear();
                        tmpRecords.add(record);
                    }
                }
            }
        }
        if(tmpRecords.size()>=trendLength){
            resultWrappers.add(harvestResult(tmpRecords,2));
        }
        return resultWrappers;
    }
    private static ResultWrapper harvestResult(List<StockRecord> records,int type){
        List<StockRecord> recordsCopy = new ArrayList<StockRecord>(records);
        ResultWrapper resultWrapper = new ResultWrapper();
        resultWrapper.setDays(recordsCopy.size());
        resultWrapper.setType(type);
        resultWrapper.setStockCode(recordsCopy.get(0).getStockCode());
        resultWrapper.setRecords(recordsCopy);
        resultWrapper.setDifference(Precision.round(Math.abs(recordsCopy.get(0).getMacdComputed()-recordsCopy.get(records.size()-1).getMacdComputed()),2));
        return resultWrapper;
    }
}
